package com.info3k.client.components;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.info3k.client.Info3K;
import com.info3k.client.domain.Address;
import com.info3k.client.utils.ToolsClient;

public class AddressListWithSearch extends Composite {

	private TextBox filterBox = new TextBox();
	private Button filterButton = new Button(Info3K.msgs.search());
	
	private HorizontalPanel panel1 = new HorizontalPanel();
	private VerticalPanel panel2 = new VerticalPanel();
	
	private boolean selectable = false;
	
	private List<AddressRenderer> addressRenderers;
	
	private Info3K info3k;
	
	private Pagination pagination = new Pagination(10);
	
	private String filterText;

	public AddressListWithSearch(boolean selectable, Info3K info, String cHeight, Address[] addresses){
		this.info3k = info;
		this.selectable = selectable;
		VerticalPanel panel = new VerticalPanel();
		initWidget(panel);
		panel.setWidth("100%");
		
		panel.add(panel1);
		panel.setCellWidth(panel1, "100%");
		panel1.setWidth("100%");
		panel.add(new HTML("<div class=\"h_line\"></div>"));
		panel.add(pagination);
		panel.add(new HTML("<div class=\"h_line\"></div>"));
		panel.setCellHorizontalAlignment(pagination, VerticalPanel.ALIGN_RIGHT);

		panel2.setWidth("100%");
		
		if(selectable){
			ScrollPanel scroll = new ScrollPanel(panel2);
			scroll.setHeight("350px");
			panel.add(scroll);
			panel.setCellWidth(scroll, "100%");
		} else {
			panel.add(panel2);
			panel.setCellWidth(panel2, "100%");
		}
		
		filterBox.setWidth("95%");
		panel1.add(filterBox);
		panel1.add(filterButton);
		panel1.setCellWidth(filterBox, "88%");
		panel1.setCellWidth(filterButton, "10%");
		
		filterButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				filterText = filterBox.getText();
				callService(filterBox.getText(), pagination.getPageSize(), null);
			}
		});
		if(addresses!=null) {
			renderAddreses(ToolsClient.fromArrayToCollection(addresses), true);
		}
		
		pagination.addValueChangeHandler(new ValueChangeHandler<Integer>(){
			public void onValueChange(ValueChangeEvent<Integer> event) {
				callService(filterText, pagination.getPageSize(), event.getValue());
			}
		});
	}
	
	private void callService(String filter, Integer pageSize, Integer current){
		Info3K.loader.setVisible(true);
		Info3K.infoService.getAddressesByFilter(filter, pageSize, current, new AsyncCallback<List<Address>>(){
			public void onFailure(Throwable caught) {
				Info3K.loader.setVisible(false);
				InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
			}

			public void onSuccess(List<Address> result) {
				Info3K.loader.setVisible(false);
				if(result.size()>0 && result.get(0).getLength()!=null){
					pagination.setLength(result.get(0).getLength());
					pagination.render(0);
				}
				renderAddreses(result, false);
			}
		});
	}
	
	private void renderAddreses(List<Address> addresses, boolean checked){
		panel2.clear();
		if(addressRenderers!=null){
			List<AddressRenderer> tempList = new ArrayList<AddressRenderer>();
			for (AddressRenderer addressR : addressRenderers) {
				if(addressR.isAddressSelected()){
					AddressRenderer rend = new AddressRenderer(addressR.getAddress(), selectable, info3k);
					rend.clickCheckbox();
					panel2.add(rend);
					panel2.add(new HTML("<hr>"));
					tempList.add(rend);		
				}
			}
			addressRenderers = tempList;
		}
		if(addressRenderers==null) addressRenderers = new ArrayList<AddressRenderer>();
		for (Address address : addresses) {
			AddressRenderer rend = new AddressRenderer(address, selectable, info3k);
			rend.selected.setValue(checked);
			rend.setAddressSelected(checked);
			if(!containsAddressRenderer(addressRenderers, rend)){
				addressRenderers.add(rend);
				panel2.add(rend);
				panel2.add(new HTML("<hr>"));
			}
		}
		if(addresses.size()==0) panel2.add(new HTML(Info3K.msgs.noAddressesFound()));
	}
	
	private Boolean containsAddressRenderer(List<AddressRenderer> list, AddressRenderer rend){
		for (AddressRenderer addressRenderer : list) {
			if(rend.getAddress().getAddress().equals(addressRenderer.getAddress().getAddress()) && rend.getAddress().getHouseNumber().equals(addressRenderer.getAddress().getHouseNumber())){
				return true;
			}
		}
		return false;
	}
	
	public List<AddressRenderer> getAddressRenderers() {
		return addressRenderers;
	}

	public void setAddressRenderers(List<AddressRenderer> addressRenderers) {
		this.addressRenderers = addressRenderers;
	}
}
